package com.queue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestQueueyuanli {
    public  static void main(String []args)
    {
        final Object o=new Object();
        //final BlockingQueue<String> queue=new ArrayBlockingQueue<String>(2);
        final BoundedBuffer queue =new BoundedBuffer();
        for(int i=0;i<2;i++)
        {
            new Thread(new Runnable() {
                public void run() {
                    while (true) {
                        try {
                            //Thread.sleep((int)Math.random()*10000000);
                            Thread.sleep(400);
                            System.out.println(Thread.currentThread().getName() + "准备生产汽车");
                            queue.put("qiche");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "生产汽车完毕，已有" + queue.size() + "辆汽车");

                    }


                }
            }).start();
        }

        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        //Thread.sleep((int)Math.random()*10000000);
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName() + "准备提走汽车");

                        queue.take();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "已经提走汽车,还有" + queue.size() + "辆汽车");
                }


            }
        }).start();
    }
}
class BoundedBuffer {
    final Lock lock = new ReentrantLock();
    final Condition notFull  = lock.newCondition();//notFull代表取能否放数据
    final Condition notEmpty = lock.newCondition();//notEmpoty代表能否取数据

    final Object[] items = new Object[5];
    int putptr, takeptr, count;

    public void put(Object x) throws InterruptedException {
        lock.lock(); try {
            while (count == items.length)
                notFull.await();
            items[putptr] = x;
            if (++putptr == items.length) putptr = 0;
            ++count;
            notEmpty.signal();
        } finally { lock.unlock();   }
    }

    public Object take() throws InterruptedException {
        lock.lock(); try {
            while (count == 0)
                notEmpty.await();
            Object x = items[takeptr];
            if (++takeptr == items.length) takeptr = 0;
            --count;
            notFull.signal();
            return x;
        } finally { lock.unlock(); }
    }
    public int size()
    {
        return count;
    }
}
